package com.regent.central.bill.repository;

import com.regent.central.bill.common.SaleOrderType;
import com.regent.central.bill.core.SaleOrder;
import com.regent.central.bill.dto.delivery.DeliverySaleOrderDTO;
import com.regent.central.bill.dto.sale_order.*;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import tk.mybatis.mapper.common.Mapper;

import java.math.BigDecimal;
import java.util.List;

@Repository
public interface SaleOrderMapper extends Mapper<SaleOrder> {

    Integer getMaxOrderNoOfUnitIdAndOrderDay(
            @Param("unitID") String unitID,
            @Param("orderDay") String orderDay
    );

    void setMerchandiser(
            @Param("orderId") String orderId,
            @Param("merchandiserId") String merchandiserId
    );

    void setAddress(
            @Param("orderId") String orderId,
            @Param("addressId") String addressId
    );

    BigDecimal getLastPrice(
            @Param("unitId") String unitId,
            @Param("goodsId") String goodsId,
            @Param("customerId") String customerId
    );

    List<String> getHistoryOrderIds(
            @Param("unitId") String unitId,
            @Param("customerId") String customerId,
            @Param("startSearchTime") String startSearchTime
    );

    List<SaleOrderListDTO> getHistoryOrderList(
            @Param("saleOrderIds") List<String> saleOrderIds
    );

    List<String> getHistoryStyleOrderIds(
            @Param("unitId") String unitId,
            @Param("customerId") String customerId,
            @Param("startSearchTime") String startSearchTime,
            @Param("styleId") String styleId
    );

    List<SaleOrderListDTO> getHistoryStyleOrderList(
            @Param("saleOrderIds") List<String> saleOrderIds,
            @Param("styleId") String styleId
    );

    List<String> getOwedSaleOrderIds(
            @Param("unitId") String unitId,
            @Param("customerId") String customerId,
            @Param("startSearchTime") String startSearchTime,
            @Param("startTime") String startTime,
            @Param("endTime") String endTime,
            @Param("sortBy") String sortBy,
            @Param("sortAs") Integer sortAs,
            @Param("keyword") String keyword
    );


    List<DeliverySaleOrderDTO> getCreatedSaleOrders(
            @Param("saleOrderIds") List<String> saleOrderIds,
            @Param("sortBy") String sortBy,
            @Param("sortAs") Integer sortAs
    );

    /**
     * 改单-货品-SKU
     *
     * @param saleOrderIds 销售单ID
     * @return 改单-货品-SKU 数量
     */
    List<DeliverySaleOrderDTO> getModifiedSaleOrders(
            @Param("saleOrderIds") List<String> saleOrderIds
    );

    /**
     * 改单-货品-SKU
     *
     * @param saleOrderIds 销售单ID
     * @return 改单-货品-SKU 数量
     */
    List<DeliverySaleOrderDTO> getDeliveredSaleOrders(
            @Param("saleOrderIds") List<String> saleOrderIds
    );

    /**
     * 获取销售单的抹零金额
     *
     * @param saleOrderId 销售单ID
     * @return 该销售单的抹零金额
     */
    BigDecimal getOddment(
            @Param("saleOrderId") String saleOrderId
    );

    /**
     * 更新销售单的本单应付
     *
     * @param saleOrderId    销售单ID
     * @param amountExpected 本单应付
     */
    void updateAmountExpected(
            @Param("saleOrderId") String saleOrderId,
            @Param("amountExpected") BigDecimal amountExpected
    );

    /**
     * 更新销售单的总收/退款
     *
     * @param saleOrderId   销售单ID
     * @param amountArrived 总收/退款
     */
    void updateAmountArrived(
            @Param("saleOrderId") String saleOrderId,
            @Param("amountArrived") BigDecimal amountArrived
    );

    /**
     * 更新销售单的总核进/核出金额
     *
     * @param saleOrderId   销售单ID
     * @param amountCleared 总核进/核出金额
     */
    void updateAmountCleared(
            @Param("saleOrderId") String saleOrderId,
            @Param("amountCleared") BigDecimal amountCleared,
            @Param("amountClearedIn") BigDecimal amountClearedIn,
            @Param("amountClearedOut") BigDecimal amountClearedOut
    );

    /**
     * 更新销售单的结欠金额
     *
     * @param saleOrderId  销售单ID
     * @param amountRemain 结欠金额
     */
    void updateAmountRemain(
            @Param("saleOrderId") String saleOrderId,
            @Param("amountRemain") BigDecimal amountRemain
    );

    /**
     * 更新销售单的销售总数
     *
     * @param saleOrderId 销售单ID
     * @param totalSold   销售总数
     */
    void updateTotalSold(
            @Param("saleOrderId") String saleOrderId,
            @Param("totalSold") BigDecimal totalSold
    );

    /**
     * 更新销售单的销售总数
     *
     * @param saleOrderId  销售单ID
     * @param totalCreated 销售总数
     */
    void updateTotalCreated(
            @Param("saleOrderId") String saleOrderId,
            @Param("totalCreated") BigDecimal totalCreated
    );

    /**
     * 更新销售单的改他单总数
     *
     * @param saleOrderId   销售单ID
     * @param totalModified 改他单总数
     */
    void updateTotalModified(
            @Param("saleOrderId") String saleOrderId,
            @Param("totalModified") BigDecimal totalModified,
            @Param("totalModifiedInc") BigDecimal totalModifiedInc,
            @Param("totalModifiedDec") BigDecimal totalModifiedDec
    );

    /**
     * 更新销售单的退货总数
     *
     * @param saleOrderId   销售单ID
     * @param totalReturned 退货总数
     */
    void updateTotalReturned(
            @Param("saleOrderId") String saleOrderId,
            @Param("totalReturned") BigDecimal totalReturned
    );

    /**
     * 更新销售单的发货总数
     *
     * @param saleOrderId    销售单ID
     * @param totalDelivered 发货总数
     */
    void updateTotalDelivered(
            @Param("saleOrderId") String saleOrderId,
            @Param("totalDelivered") BigDecimal totalDelivered
    );

    /**
     * 更新销售单的欠货总数
     *
     * @param saleOrderId 销售单ID
     * @param totalOwed   欠货总数
     */
    void updateTotalOwed(
            @Param("saleOrderId") String saleOrderId,
            @Param("totalOwed") BigDecimal totalOwed
    );

    /**
     * 更新销售单的开单总额
     *
     * @param saleOrderId   销售单ID
     * @param amountCreated 开单总额
     */
    void updateAmountCreated(
            @Param("saleOrderId") String saleOrderId,
            @Param("amountCreated") BigDecimal amountCreated
    );

    /**
     * 更新销售单的改单总额
     *
     * @param saleOrderId    销售单ID
     * @param amountModified 改单总额
     */
    void updateAmountModified(
            @Param("saleOrderId") String saleOrderId,
            @Param("amountModified") BigDecimal amountModified
    );

    /**
     * 更新销售单的退货总额
     *
     * @param saleOrderId    销售单ID
     * @param amountReturned 退货总额
     */
    void updateAmountReturned(
            @Param("saleOrderId") String saleOrderId,
            @Param("amountReturned") BigDecimal amountReturned
    );

    /**
     * 查询销售单
     *
     * @param unitId          组织ID
     * @param startTime       开始时间
     * @param endTime         结束时间
     * @param userIds         用户ID
     * @param types           单据类型
     * @param saleOrderStatus 销售单状态
     * @param receiptStatus   收款单状态
     * @param startSearchTime 开始搜索时间
     * @return 销售单集合
     */
    List<SaleOrderQueryDTO> query(
            @Param("unitId") String unitId,
            @Param("startTime") String startTime,
            @Param("endTime") String endTime,
            @Param("userIds") List<String> userIds,
            @Param("types") List<SaleOrderType> types,
            @Param("saleOrderStatus") List<SaleOrderQueryStatus> saleOrderStatus,
            @Param("receiptStatus") List<ReceiptQueryStatus> receiptStatus,
            @Param("startSearchTime") String startSearchTime
    );

    /**
     * 获取销售单详情
     *
     * @param saleOrderId 销售单ID
     * @return 销售单详情或{@code null} 如果不存在
     */
    SaleOrderDetailDTO detail(
            @Param("saleOrderId") String saleOrderId
    );

    /**
     * 修改销售单的抹零金额
     *
     * @param saleOrderId 销售单ID
     * @param oddment     抹零金额
     */
    void setOddment(
            @Param("saleOrderId") String saleOrderId,
            @Param("oddment") BigDecimal oddment
    );

    /**
     * 撤销销售单
     *
     * @param saleOrderId 销售单ID
     */
    void cancel(
            @Param("saleOrderId") String saleOrderId
    );

    /**
     * 查询可核销的销售单列表
     *
     * @param unitId          组织ID
     * @param customerId      客户ID
     * @param startSearchTime 开始搜索时间
     * @return 可核销的销售单列表
     */
    List<SaleOrderQueryDTO> clearables(
            @Param("unitId") String unitId,
            @Param("customerId") String customerId,
            @Param("startSearchTime") String startSearchTime
    );

}